// Author	: damphat@gmail.com
// Created	: 01/12/2008

#pragma once
#include "vn/IOCommon.h"
#include "vn/File.h"

IO_BEGIN


class File {
public:
	static FileStream *
	Create(String path, FileOptions options = FileOptions::None) {
		FileStream *pfs = new FileStream();
		try {
			pfs->Open(path, FileMode::Create, FileAccess::ReadWrite, FileShare::None, options);
		}
		catch(...) {
			delete pfs;
			throw;
		}
		return pfs;
	}

	static FileStream *
	Open(String path, FileMode mode, FileAccess access, FileShare share = FileShare::None) {
		FileStream *pfs = new FileStream();
		try {
			pfs->Open(path, mode, access, share);
		}
		catch(...) {
			delete pfs;
			throw;
		}
		return pfs;
	}

	static FileStream *
	Open(String path, FileMode mode) {
	  return Open(
		  path,
		  mode, 
		  (mode == FileMode::Append) ? FileAccess::Write : FileAccess::ReadWrite, 
		  FileShare::None);
	}

	static FileStream *
	OpenRead(String path) {
		return Open(path, FileMode::Open, FileAccess::Read, FileShare::Read);
	}

	static FileStream *
	OpenWrite(String path) {
		return Open(path, FileMode::OpenOrCreate, FileAccess::Write, FileShare::None);
	}


	// cannot use for directory
	// invalid param
	// success
	// not found
	// permission
	// question:
	//   Move to recycle bin?
	//   Safe deleted?
	// 
	static bool
	Delete(String path) {
		BOOL bret = DeleteFile(path.C_STR());
		if(!bret) {
			if(GetLastError() == ERROR_FILE_NOT_FOUND) {
				return false;
			}
			CHECK_IO(false);
		}
		return true;
	}

	// check for file exist
	static bool
	Exists(String path) {
		DWORD dwret = GetFileAttributes(path.C_STR());
		return dwret != INVALID_FILE_ATTRIBUTES;
	}

	//Find()
	//DiskFree
	//Notify
	//GetFileAttribute
	//CurrentDirectory
	//CommonDirectory
	//FreeDiskSpace


	static void
	Copy(String srcFileName, String desFileName, bool overwrite = false) {
		BOOL bret = CopyFile(srcFileName.C_STR(), desFileName.C_STR(), !overwrite);
		CHECK_IO(bret);
	}

	static void
	Move(String srcPath, String desPath) {
		BOOL bret = MoveFile(srcPath.C_STR(), desPath.C_STR());
		CHECK_IO(bret);
	}

	static FileAttributes
	GetAttributes(String path) {
		DWORD dwAttrs = GetFileAttributes(path.C_STR());
		CHECK_IO(dwAttrs != INVALID_FILE_ATTRIBUTES);
		return dwAttrs;
	}

	static void
	SetAttributes(String path, FileAttributes attributes) {
		BOOL bret = SetFileAttributes(path.C_STR(), attributes);
		CHECK_IO(bret);
	}
};

IO_END
